home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / twnsck12.zip / SRC\TSHOST.C < prev    next >
C/C++ Source or Header  |  1994-11-20  |  9KB  |  426 lines

  1. /*
  2.  *  TwinSock - "Troy's Windows Sockets"
  3.  *
  4.  *  Copyright (C) 1994  Troy Rollo <troy@cbme.unsw.EDU.AU>
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include <sys/types.h>
  22. #include <sys/time.h>
  23. #include <stdio.h>
  24. #include <netinet/in.h>
  25. #include <errno.h>
  26. #ifdef NEED_SELECT_H
  27. #include <sys/select.h>
  28. #endif
  29. #include "twinsock.h"
  30. #include "tx.h"
  31.  
  32. extern    void    PacketTransmitData(void *pvData, int iDataLen, int iStream);
  33.  
  34. #define    BUFFER_SIZE    1024
  35.  
  36. static    fd_set    fdsActive;
  37. static    fd_set    fdsListener;
  38. static    int    nLargestFD;
  39. static    char    achBuffer[BUFFER_SIZE];
  40. static    int    bFlushing = 0;
  41. void    FlushInput(void);
  42.  
  43. int    GetNextExpiry(struct timeval *ptvValue);
  44. void    CheckTimers(void);
  45. extern    char    *sys_errlist[];
  46.  
  47. #define    TIMER_ID_SEND        0
  48. #define    TIMER_ID_RECEIVE    1
  49. #define    TIMER_ID_FLUSH        2
  50.  
  51. int    BumpLargestFD(int iValue)
  52. {
  53.     if (iValue > nLargestFD)
  54.         nLargestFD = iValue;
  55.     FD_SET(iValue, &fdsActive);
  56. };
  57.  
  58. int    SetListener(int iValue)
  59. {
  60.     FD_SET(iValue, &fdsListener);
  61. }
  62.  
  63. int    SetClosed(int iValue)
  64. {
  65.     FD_CLR(iValue, &fdsListener);
  66.     FD_CLR(iValue, &fdsActive);
  67. }
  68.  
  69. main(int argc, char **argv)
  70. {
  71.     fd_set    fdsRead, fdsWrite, fdsExcept, fdsDummy;
  72.     int    nRead;
  73.     int    i;
  74.     int    iResult;
  75.     struct    sockaddr_in saSource;
  76.     int    nSourceLen;
  77.     int    s;
  78.     struct    timeval tvZero;
  79.     struct    timeval tv;
  80.  
  81.     fprintf(stderr, "TwinSock Host 1.1 (pre release)\n");
  82.     fprintf(stderr, "Copyright 1994 Troy Rollo\n");
  83.     fprintf(stderr, "This program is free software\n");
  84.     fprintf(stderr, "See the file COPYING for details\n");
  85.     fprintf(stderr, "\nStart your TwinSock client now\n");
  86.     fprintf(stderr, "!@$TSStart$@\n");
  87.  
  88.     if (isatty(0))
  89.         InitTerm();
  90.     nLargestFD = 0;
  91.     FD_ZERO(&fdsActive);
  92.     FD_ZERO(&fdsWrite);
  93.     FD_ZERO(&fdsExcept);
  94.  
  95.     FD_SET(0, &fdsActive);
  96.  
  97.     while(1)
  98.     {
  99.         fdsRead = fdsActive;
  100.         iResult = select(nLargestFD + 1,
  101.                 &fdsRead,
  102.                 &fdsWrite,
  103.                 &fdsExcept,
  104.                 GetNextExpiry(&tv) ? &tv : 0);
  105.         CheckTimers();
  106.         if (iResult <= 0)
  107.             continue;
  108.         if (FD_ISSET(0, &fdsRead))
  109.         {
  110.             nRead = read(0, achBuffer, BUFFER_SIZE);
  111.             if (nRead > 0)
  112.             {
  113.                 if (bFlushing)
  114.                     FlushInput();
  115.                 else
  116.                     PacketReceiveData(achBuffer, nRead);
  117.             }
  118.             else if (nRead == 0 && !isatty(0))
  119.             {
  120.                 exit(0);
  121.             }
  122.         }
  123.         for (i = 3; i <= nLargestFD; i++)
  124.         {
  125.             if (FD_ISSET(i, &fdsRead))
  126.             {
  127.                 FD_ZERO(&fdsDummy);
  128.                 FD_SET(i, &fdsDummy);
  129.                 tvZero.tv_sec = tvZero.tv_usec = 0;
  130.                 if (select(i + 1,
  131.                         &fdsDummy,
  132.                         &fdsWrite,
  133.                         &fdsExcept,
  134.                         &tvZero) != 1)
  135.                     continue; /* Select lied */
  136.  
  137.                 nSourceLen = sizeof(saSource);
  138.                 if (FD_ISSET(i, &fdsListener))
  139.                 {
  140.                     s = accept(i,
  141.                         &saSource,
  142.                         &nSourceLen);
  143.                     if (s == -1)
  144.                         continue;
  145.                     s = htonl(s);
  146.                     BumpLargestFD(s);
  147.                     SendSocketData(i,
  148.                         &s,
  149.                         sizeof(s),
  150.                         &saSource,
  151.                         nSourceLen,
  152.                         FN_Accept);
  153.                 }
  154.                 else
  155.                 {
  156.                     nRead = recvfrom(i,
  157.                             achBuffer,
  158.                             BUFFER_SIZE,
  159.                             0,
  160.                             &saSource,
  161.                             &nSourceLen);
  162.                     if (nRead < 0 &&
  163.                         errno == ENOTCONN)
  164.                     {
  165.                         /* Was a datagram socket */
  166.                         SetClosed(i);
  167.                         continue;
  168.                     }
  169.                     if (nRead >= 0)
  170.                         SendSocketData(i,
  171.                             achBuffer,
  172.                             nRead,
  173.                             &saSource,
  174.                             nSourceLen,
  175.                             FN_Data);
  176.                     if (nRead == 0)
  177.                         SetClosed(i);
  178.                 }
  179.             }
  180.         }
  181.     }
  182. }
  183.  
  184.  
  185. void
  186. SetTransmitTimeout(void)
  187. {
  188.     KillTimer(TIMER_ID_SEND);
  189.     SetTimer(TIMER_ID_SEND, 3000);
  190. }
  191.  
  192. void
  193. KillTransmitTimeout(void)
  194. {
  195.     KillTimer(TIMER_ID_SEND);
  196. }
  197.  
  198. void    SetReceiveTimeout(void)
  199. {
  200.     KillTimer(TIMER_ID_RECEIVE);
  201.     SetTimer(TIMER_ID_RECEIVE, 1500);
  202. }
  203.  
  204. void    KillReceiveTimeout(void)
  205. {
  206.     KillTimer(TIMER_ID_RECEIVE);
  207. }
  208.  
  209. static    struct    timeval atvTimers[3];
  210. static    int    iTimersOn;
  211. static    int    iTimerRunning;
  212. static    int    iInTimer = 0;
  213.  
  214.  
  215. int    FireTimer(int iTimer)
  216. {
  217.     switch(iTimer)
  218.     {
  219.     case TIMER_ID_SEND:
  220.         TimeoutReceived();
  221.         break;
  222.  
  223.     case TIMER_ID_RECEIVE:
  224.         PacketReceiveData(0, 0);
  225.         break;
  226.  
  227.     case TIMER_ID_FLUSH:
  228.         bFlushing = 0;
  229.         break;
  230.     }
  231. }
  232.  
  233. int    GetNextExpiry(struct timeval *ptvValue)
  234. {
  235.     struct    timeval    tvNow;
  236.     struct    timezone tzDummy;
  237.     struct    timeval    tvGo;
  238.     int    i;
  239.  
  240.     if (!iTimersOn)
  241.         return 0;
  242.  
  243.     tvGo.tv_sec = 0x7fffffff;
  244.     tvGo.tv_usec = 0;
  245.     for (i = 0; i < 3; i++)
  246.     {
  247.         if (!(iTimersOn & (1 << i)))
  248.             continue;
  249.         if (atvTimers[i].tv_sec < tvGo.tv_sec ||
  250.             (atvTimers[i].tv_sec == tvGo.tv_sec &&
  251.              atvTimers[i].tv_usec < tvGo.tv_usec))
  252.         {
  253.             tvGo = atvTimers[i];
  254.             iTimerRunning = i;
  255.         }
  256.     }
  257.     gettimeofday(&tvNow, &tzDummy);
  258.     ptvValue->tv_sec = tvGo.tv_sec - tvNow.tv_sec;
  259.     ptvValue->tv_usec = tvGo.tv_usec - tvNow.tv_usec;
  260.     while (ptvValue->tv_usec < 0)
  261.     {
  262.         ptvValue->tv_usec += 1000000l;
  263.         ptvValue->tv_sec--;
  264.     }
  265.     while (ptvValue->tv_usec >= 1000000l)
  266.     {
  267.         ptvValue->tv_usec -= 1000000l;
  268.         ptvValue->tv_sec++;
  269.     }
  270.     if (ptvValue->tv_sec < 0)
  271.     {
  272.         ptvValue->tv_sec = 0;
  273.         ptvValue->tv_usec = 100;
  274.     }
  275.     if (!ptvValue->tv_sec &&
  276.         ptvValue->tv_usec < 100)
  277.         ptvValue->tv_usec = 100;
  278.     return 1;
  279. }
  280.  
  281. void    CheckTimers(void)
  282. {
  283.     struct    timeval    tvNow;
  284.     struct    timezone tzDummy;
  285.     int    i;
  286.  
  287.     gettimeofday(&tvNow, &tzDummy);
  288.     for (i = 0; i < 3; i++)
  289.     {
  290.         if (!(iTimersOn & (1 << i)))
  291.             continue;
  292.         if (atvTimers[i].tv_sec < tvNow.tv_sec ||
  293.             (atvTimers[i].tv_sec == tvNow.tv_sec &&
  294.              atvTimers[i].tv_usec < tvNow.tv_usec))
  295.         {
  296.             KillTimer(i);
  297.             FireTimer(i);
  298.         }
  299.     }
  300. }
  301.  
  302. int    SetTimer(int idTimer, int iTime)
  303. {
  304.     struct    timeval        tvNow;
  305.     struct    timezone    tzDummy;
  306.  
  307.     gettimeofday(&tvNow, &tzDummy);
  308.     atvTimers[idTimer] = tvNow;
  309.     atvTimers[idTimer].tv_usec += (long) iTime % 1000l * 1000l;
  310.     atvTimers[idTimer].tv_sec += iTime / 1000;
  311.     while (atvTimers[idTimer].tv_usec > 1000000l)
  312.     {
  313.         atvTimers[idTimer].tv_sec++;
  314.         atvTimers[idTimer].tv_usec -= 1000000l;
  315.     }
  316.     iTimersOn |= (1 << idTimer);
  317. }
  318.  
  319. int    KillTimer(int idTimer)
  320. {
  321.     iTimersOn &= ~(1 << idTimer);
  322. }
  323.  
  324. void    Shutdown(void)
  325. {
  326.     if (isatty(0))
  327.         UnInitTerm();
  328.     fprintf(stderr, "\nTwinSock Host Finished\n");
  329.     exit(0);
  330. }
  331.  
  332. int
  333. SendData(void *pvData, int iDataLen)
  334. {
  335.     int    iLen;
  336.     int    nWritten;
  337.  
  338.     if (bFlushing)
  339.         return iDataLen; /* Lie */
  340.     iLen = iDataLen;
  341.  
  342.     while (iLen > 0)
  343.     {
  344.         nWritten = write(1, pvData, iDataLen);
  345.         if (nWritten > 0)
  346.             iLen -= nWritten;
  347.     }
  348.     return iDataLen;
  349. }
  350.  
  351. void
  352. FlushInput(void)
  353. {
  354.     bFlushing = 1;
  355.     SetTimer(TIMER_ID_FLUSH, 1500);
  356. }
  357.  
  358. static void
  359. SendInitResponse(void)
  360. {
  361.     struct    tx_request txr;
  362.  
  363.     txr.iType = htons(FN_Init);
  364.     txr.nArgs = 0;
  365.     txr.nLen = htons(10);
  366.     txr.id = -1;
  367.     txr.nError = 0;
  368.     PacketTransmitData(&txr, 10, -2);
  369. }
  370.  
  371. void
  372. DataReceived(void *pvData, int iLen)
  373. {
  374.     static    struct tx_request *ptxr = 0;
  375.     static    struct tx_request txrHeader;
  376.     static    int    nBytes = 0;
  377.     short    nPktLen;
  378.     enum Functions ft;
  379.     int    nCopy;
  380.  
  381.     while (iLen)
  382.     {
  383.         if (nBytes < 10)
  384.         {
  385.             nCopy = 10 - nBytes;
  386.             if (nCopy > iLen)
  387.                 nCopy = iLen;
  388.             memcpy((char *) &txrHeader + nBytes, pvData, nCopy);
  389.             nBytes += nCopy;
  390.             pvData = (char *) pvData + nCopy;
  391.             iLen -= nCopy;
  392.             if (nBytes == 10)
  393.             {
  394.                 nPktLen = ntohs(txrHeader.nLen);
  395.                 ptxr = (struct tx_request *) malloc(sizeof(struct tx_request) + nPktLen - 10);
  396.                 memcpy(ptxr, &txrHeader, 10);
  397.             }
  398.         }
  399.         if (nBytes >= 10)
  400.         {
  401.             nPktLen = ntohs(txrHeader.nLen);
  402.             ft = (enum Functions) ntohs(txrHeader.iType);
  403.             nCopy = nPktLen - nBytes;
  404.             if (nCopy > iLen)
  405.                 nCopy = iLen;
  406.             if (nCopy)
  407.             {
  408.                 memcpy((char *) ptxr + nBytes, pvData, nCopy);
  409.                 nBytes += nCopy;
  410.                 pvData = (char *) pvData + nCopy;
  411.                 iLen -= nCopy;
  412.             }
  413.             if (nBytes == nPktLen)
  414.             {
  415.                 if (ft == FN_Init)
  416.                     SendInitResponse();
  417.                 else
  418.                     ResponseReceived(ptxr);
  419.                 free(ptxr);
  420.                 ptxr = 0;
  421.                 nBytes = 0;
  422.             }
  423.         }
  424.     }
  425. }
  426.